package com.zznzzn.myweb.socket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zznzzn.myweb.pojo.Record;
import com.zznzzn.myweb.pojo.User;
import com.zznzzn.myweb.service.RecordService;
import com.zznzzn.myweb.service.UserService;
import com.zznzzn.myweb.util.Base64Util;
import com.zznzzn.myweb.util.JWTUtil;
import com.zznzzn.myweb.util.RespHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;

//@Component
//@ServerEndpoint("/api/websocket/{uuid}")
public class WebSocket {
//    @Autowired
    private RecordService recordService;
//
//    @Autowired
    private UserService userService;

    private Session session;


    private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>();
    private static Map<String, Session> sessionPool = new HashMap<String, Session>();
    private static Map<String, String> chattingPool = new HashMap<String, String>();

    @OnOpen
    public void onOpen(Session session, @PathParam(value = "uuid") String senderuuid) {
        this.session = session;
        webSockets.add(this);
        sessionPool.put(senderuuid, session);
        System.out.println(senderuuid);
        System.out.println("【websocket消息】有新的连接，总数为:" + webSockets.size());
    }

    @OnClose
    public void onClose() {
        webSockets.remove(this);
        System.out.println("【websocket消息】连接断开，总数为:" + webSockets.size());
    }

    @OnMessage
    public void onMessage(String message) {
        JSONObject jsonObject = JSON.parseObject(message);
        System.out.println(jsonObject.keySet());
        String fromid = jsonObject.getString("from");
        String type = jsonObject.getString("type");
        String token = jsonObject.getString("token");

        User userfrom = userService.getUserById(JWTUtil.getUserId(token));
        System.out.println(userfrom);
        //verify token
        if (JWTUtil.verify(token, userfrom.getUuid(), userfrom.getSalt())) {
            switch (type) {
                case "pullAllUser": {
                    List<Record> records = recordService.queryRecordsOfUuid(fromid, 100);
                    Set<User> users = new HashSet<>();
                    for (Record re : records) {
                        if (!re.getFromid().equals(fromid)) {
                            users.add(userService.harmless(userService.getUserById(re.getFromid())));
                        }
                        if (!re.getToid().equals(fromid)) {
                            users.add(userService.harmless(userService.getUserById(re.getToid())));
                        }

                    }
                    //统一返回
                    sendOneMessage(fromid, JSON.toJSONString(RespHelper.buildSuccess("pullAllUser", users)));
                    break;
                }
                case "pullOneUser" :{
                    String to = jsonObject.getString("to");
                    User user = userService.harmless(userService.getUserById(to));
                    sendOneMessage(fromid, JSON.toJSONString(RespHelper.buildSuccess("pullOneUser", user)));
                    break;
                }
                case "pullMore": {
                    String toid1 = jsonObject.getString("to");
                    Date last = jsonObject.getDate("last");
                    List<Record> records1 = recordService.queryRecordsBetweenUuidByAfter(fromid, toid1, last);
                    sendOneMessage(fromid, JSON.toJSONString(RespHelper.buildSuccess("pullMore", records1)));
                    break;
                }
                case "subscribe": {

                    //换一个聊天对象时
                    String toid = jsonObject.getString("to");
                    if (chattingPool.containsKey(fromid)) {
                        chattingPool.replace(fromid, toid);
                    } else {
                        chattingPool.put(fromid, toid);
                    }
                    List<Record> records2 = recordService.queryRecordsBetweenUuidBylimit(fromid, toid, 50);
                    // 将接受的消息设为已读
                    recordService.setReceived(toid, fromid);
                    sendOneMessage(fromid, JSON.toJSONString(RespHelper.buildSuccess("subscribe", records2)));
                    break;
                }
                case "chat": {
                    //new chat record
                    String content = "";
                    try {
                        content = Base64Util.fullDecode(jsonObject.getString("content"));

                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    String toid = jsonObject.getString("to");
                    Record record = new Record();
                    record.setChatid(Base64Util.newUUID());
                    record.setContent(content);
                    record.setFromid(fromid);
                    record.setToid(toid);
                    if (chattingPool.containsKey(fromid)  //发送者有发送对象
                            && chattingPool.containsKey(toid) //接受者有发送对象
                            && sessionPool.containsKey(fromid) //发送者在线
                            && sessionPool.containsKey(toid) //接受者在线
                            && chattingPool.get(fromid).equals(toid) //发送者将接受者设为接受者
                            && chattingPool.get(toid).equals(fromid) //接受者将发送者设为接受者
                    ) {

                        //当发送者将接受者加入chattingpool 且接受者在线 且接受者也将发送者加入了chattingpool时，直接发送
                        record.setStatus(1);
                        //发送给接受者
                        sendOneMessage(toid, JSON.toJSONString(RespHelper.buildSuccess("chat", record)));
                    }
                    recordService.newRecord(record);
                    //回复给发送者
                    sendOneMessage(fromid, JSON.toJSONString(RespHelper.buildSuccess("chat", record)));
                    System.out.println(record);
                    break;

                }
                case "bye": {
                    chattingPool.remove(fromid);
                    sendOneMessage(fromid, JSON.toJSONString(RespHelper.buildSuccess("bye")));
                    System.out.println("bye!");
                    break;
                }
            }


        } else {
            sendOneMessage(fromid, "token验证不通过");
            webSockets.remove(this);
        }


        System.out.println("【websocket消息】收到客户端消息:" + message);
    }

    // 此为广播消息
    public void sendAllMessage(String message) {
        for (WebSocket webSocket : webSockets) {
            System.out.println("【websocket消息】广播消息:" + message);
            try {
                webSocket.session.getAsyncRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 此为单点消息
    public void sendOneMessage(String senderid, String message) {
        Session session = sessionPool.get(senderid);
        if (session != null) {
            try {
                session.getAsyncRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
